package com.tbit.common.entity.vo;

import lombok.Data;
import lombok.experimental.Accessors;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Arrays;
import java.util.List;

/**
 * @author: qiu.longjie
 * @create: 2025-05-21
 */
@Data
@Accessors(chain = true)
public class DataBox<T> {

    /**
     * 数据
     */
    private T data;

    /**
     * 日增长率%
     */
    private Double dayGrowthRate;

    /**
     * 周增长率%
     */
    private Double weekGrowthRate;

    /**
     * 前7天数据,升序排序
     */
    private List<T> weekData;

    // 获取第一天数据
    public T getData() {
        if (weekData == null || weekData.isEmpty()) {
            return data;
        }
        return weekData.get(weekData.size() - 1);
    }

    // 获取前一天数据增长率 = （前一天数据 - 当天数据）/ 前一天数据
    public Double getDayGrowthRate() {
        if (weekData == null || weekData.isEmpty() || weekData.size() < 2) {
            return 0.00D;
        }
        Double previousDayData = Double.parseDouble(weekData.get(weekData.size() - 2).toString()); // 前一天数据
        Double currentDayData = Double.parseDouble(weekData.get(weekData.size() - 1).toString()); // 当天数据
        return handleRate(previousDayData - currentDayData, currentDayData);
    }

    public Double getWeekGrowthRate() {
        if (weekData == null || weekData.isEmpty() || weekData.size() < 7) {
            return 0.00D;
        }
        Double previousWeekData = Double.parseDouble(weekData.get(weekData.size() - 7).toString()); // 前一周数据
        Double currentDayData = Double.parseDouble(weekData.get(weekData.size() - 1).toString()); // 当天数据
        return handleRate(previousWeekData - currentDayData, currentDayData);
    }

    public static <T> DataBox<T> empty(Class<T> clazz) {
        return new DataBox<T>().nullData(clazz);
    }

    /**
     * 根据泛型类型自动设置默认值
     */
    public DataBox<T> nullData(Class<T> clazz) {
        if (clazz == Integer.class) {
            this.data = clazz.cast(0);
        } else if (clazz == Double.class) {
            this.data = clazz.cast(0.00D);
        } else {
            this.data = null;
        }
        this.dayGrowthRate = 0.00D;
        this.weekGrowthRate = 0.00D;
        this.weekData = Arrays.asList(data,data,data,data,data,data,data);
        return this;
    }

    private Double handleRate(Double validCount, Double totalCount) {
        if (validCount == null || totalCount == null || validCount == 0 || totalCount == 0) {
            return BigDecimal.ZERO.doubleValue();
        }
        return BigDecimal.valueOf(validCount).divide(BigDecimal.valueOf(totalCount), 4, RoundingMode.HALF_UP).multiply(ONE_HUNDRED).doubleValue();
    }

    private static final BigDecimal ONE_HUNDRED = new BigDecimal(100);
}
